home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / Mesa-3.0 / SRC / DDSAMPLE.C < prev    next >
Encoding:
C/C++ Source or Header  |  1998-06-02  |  21.7 KB  |  847 lines

  1. /* $Id: ddsample.c,v 3.1 1998/06/02 01:33:51 brianp Exp $ */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  3.0
  6.  * Copyright (C) 1995-1998  Brian Paul
  7.  *
  8.  * This library is free software; you can redistribute it and/or
  9.  * modify it under the terms of the GNU Library General Public
  10.  * License as published by the Free Software Foundation; either
  11.  * version 2 of the License, or (at your option) any later version.
  12.  *
  13.  * This library is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16.  * Library General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU Library General Public
  19.  * License along with this library; if not, write to the Free
  20.  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  */
  22.  
  23.  
  24. /*
  25.  * $Log: ddsample.c,v $
  26.  * Revision 3.1  1998/06/02 01:33:51  brianp
  27.  * updated for v3.0 device driver changes
  28.  *
  29.  * Revision 3.0  1998/01/31 20:50:03  brianp
  30.  * initial rev
  31.  *
  32.  */
  33.  
  34.  
  35.  
  36. /*
  37.  * This is a sample template for writing new Mesa device drivers.
  38.  * You'll have to rewrite much of the code below.
  39.  *
  40.  * Let's say you're interfacing Mesa to a window/operating system
  41.  * called FOO.  Replace all occurances of FOOMesa with the real name
  42.  * you select for your interface  (i.e. XMesa, WMesa, AmigaMesa).
  43.  *
  44.  * You'll have to design an API for clients to use, defined in a
  45.  * header called Mesa/include/GL/FooMesa.h  Use the sample as an
  46.  * example.  The API should at least have functions for creating
  47.  * rendering contexts, binding rendering contexts to windows/frame
  48.  * buffers, etc.
  49.  * 
  50.  * Next, you'll have to write implementations for the device driver
  51.  * functions described in dd.h
  52.  *
  53.  * Note that you'll usually have to flip Y coordinates since Mesa's
  54.  * window coordinates start at the bottom and increase upward.  Most
  55.  * window system's Y-axis increases downward
  56.  *
  57.  * Functions marked OPTIONAL may be completely omitted by your driver.
  58.  *
  59.  * Your Makefile should compile this module along with the rest of
  60.  * the core Mesa library.
  61.  */
  62.  
  63.  
  64. #include <stdlib.h>
  65. #include "GL/FooMesa.h"
  66. #include "context.h"
  67. #include "matrix.h"
  68. #include "types.h"
  69. #include "vb.h"
  70.  
  71.  
  72.  
  73. /*
  74.  * In C++ terms, this class derives from the GLvisual class.
  75.  * Add system-specific fields to it.
  76.  */
  77. struct foo_mesa_visual {
  78.    GLvisual *gl_visual;
  79.    GLboolean db_flag;        /* double buffered? */
  80.    GLboolean rgb_flag;        /* RGB mode? */
  81.    GLuint depth;        /* bits per pixel (1, 8, 24, etc) */
  82. };
  83.  
  84.  
  85. /*
  86.  * In C++ terms, this class derives from the GLframebuffer class.
  87.  * Add system-specific fields to it.
  88.  */
  89. struct foo_mesa_buffer {
  90.    GLframebuffer *gl_buffer;    /* The depth, stencil, accum, etc buffers */
  91.    void *the_window;        /* your window handle, etc */
  92.    int Width, Height;
  93. };
  94.  
  95.  
  96.  
  97. /*
  98.  * In C++ terms, this class derives from the GLcontext class.
  99.  * Add system-specific fields to it.
  100.  */
  101. struct foo_mesa_context {
  102.    GLcontext *gl_ctx;        /* the core library context */
  103.    FooMesaVisual visual;
  104.    FooMesaBuffer Buffer;
  105.    GLuint ClearIndex;
  106.    GLubyte ClearColor[4];
  107.    GLuint CurrentIndex;
  108.    GLubyte CurrentColor[4];
  109.    /* etc... */
  110. };
  111.  
  112.  
  113. static FooMesaContext CurrentContext = 0;
  114. static FooMesaBuffer CurrentBuffer = 0;
  115.  
  116.  
  117.  
  118. static void setup_DD_pointers( GLcontext *ctx );
  119.  
  120.  
  121. /**********************************************************************/
  122. /*****              Miscellaneous device driver funcs             *****/
  123. /**********************************************************************/
  124.  
  125.  
  126. static void finish( GLcontext *ctx )
  127. {
  128.    struct foo_mesa_context *foo = (struct foo_mesa_context *) ctx->DriverCtx;
  129.    /* OPTIONAL FUNCTION: implements glFinish if possible */
  130. }
  131.  
  132.  
  133.  
  134. static void flush( GLcontext *ctx )
  135. {
  136.    struct foo_mesa_context *foo = (struct foo_mesa_context *) ctx->DriverCtx;
  137.    /* OPTIONAL FUNCTION: implements glFlush if possible */
  138. }
  139.  
  140.  
  141.  
  142. static void clear_index( GLcontext *ctx, GLuint index )
  143. {
  144.    struct foo_mesa_context *foo = (struct foo_mesa_context *) ctx->DriverCtx;
  145.    foo->ClearIndex = index;
  146. }
  147.  
  148.  
  149.  
  150. static void clear_color( GLcontext *ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a )
  151. {
  152.    struct foo_mesa_context *foo = (struct foo_mesa_context *) ctx->DriverCtx;
  153.    foo->ClearColor[0] = r;
  154.    foo->ClearColor[1] = g;
  155.    foo->ClearColor[2] = b;
  156.    foo->ClearColor[3] = a;
  157. }
  158.  
  159.  
  160.  
  161. static GLbitfield clear( GLcontext *ctx, GLbitfield mask, GLboolean all,
  162.                         GLint x, GLint y, GLint width, GLint height )
  163. {
  164.    struct foo_mesa_context *foo = (struct foo_mesa_context *) ctx->DriverCtx;
  165. /*
  166.  * Clear the specified region of the buffers indicated by 'mask'
  167.  * using the clear color or index as specified by one of the two
  168.  * functions above.
  169.  * If all==GL_TRUE, clear whole buffer, else just clear region defined
  170.  * by x,y,width,height
  171.  */
  172.  
  173.    return mask;  /* return mask of buffers remaining to be cleared */
  174. }
  175.  
  176.  
  177.  
  178. static void set_index( GLcontext *ctx, GLuint index )
  179. {
  180.    struct foo_mesa_context *foo = (struct foo_mesa_context *) ctx->DriverCtx;
  181.    foo->CurrentIndex = index;
  182. }
  183.  
  184.  
  185.  
  186. static void set_color( GLcontext *ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a )
  187. {
  188.    struct foo_mesa_context *foo = (struct foo_mesa_context *) ctx->DriverCtx;
  189.    foo->CurrentColor[0] = r;
  190.    foo->CurrentColor[1] = g;
  191.    foo->CurrentColor[2] = b;
  192.    foo->CurrentColor[3] = a;
  193. }
  194.  
  195.  
  196.  
  197. /*
  198.  * OPTIONAL FUNCTION: implement glIndexMask if possible, else
  199.  * return GL_FALSE
  200.  */
  201. static GLboolean index_mask( GLcontext *ctx, GLuint mask )
  202. {
  203.    struct foo_mesa_context *foo = (struct foo_mesa_context *) ctx->DriverCtx;
  204.    return GL_FALSE;
  205. }
  206.  
  207.  
  208.  
  209. /*
  210.  * OPTIONAL FUNCTION: implement glColorMask if possible, else
  211.  * return GL_FALSE
  212.  */
  213. static GLboolean color_mask( GLcontext *ctx, 
  214.                              GLboolean rmask, GLboolean gmask,
  215.                              GLboolean bmask, GLboolean amask)
  216. {
  217.    struct foo_mesa_context *foo = (struct foo_mesa_context *) ctx->DriverCtx;
  218.    return GL_FALSE;
  219. }
  220.  
  221.  
  222.  
  223. /*
  224.  * OPTIONAL FUNCTION: 
  225.  * Implements glLogicOp if possible.  Return GL_TRUE if the device driver
  226.  * can perform the operation, otherwise return GL_FALSE.  If GL_FALSE
  227.  * is returned, the logic op will be done in software by Mesa.
  228.  */
  229. static GLboolean logicop( GLcontext *ctx, GLenum op )
  230. {
  231.    struct foo_mesa_context *foo = (struct foo_mesa_context *) ctx->DriverCtx;
  232.    return GL_FALSE;
  233. }
  234.  
  235.  
  236.  
  237. /*
  238.  * OPTIONAL FUNCTION: enable/disable dithering if applicable
  239.  */
  240. static void dither( GLcontext *ctx, GLboolean enable )
  241. {
  242.    struct foo_mesa_context *foo = (struct foo_mesa_context *) ctx->DriverCtx;
  243. }
  244.  
  245.  
  246.  
  247. /*
  248.  * Set the current drawing/reading buffer, return GL_TRUE or GL_FALSE
  249.  * for success/failure.
  250.  */
  251. static GLboolean set_buffer( GLcontext *ctx, GLenum mode )
  252. {
  253.    struct foo_mesa_context *foo = (struct foo_mesa_context *) ctx->DriverCtx;
  254.    setup_DD_pointers( ctx );
  255.    return GL_TRUE;
  256. }
  257.  
  258.  
  259.  
  260. /*
  261.  * Return the width and height of the current buffer.
  262.  * If anything special has to been done when the buffer/window is
  263.  * resized, do it now.
  264.  */
  265. static void get_buffer_size( GLcontext *ctx, GLuint *width, GLuint *height )
  266. {
  267.    struct foo_mesa_context *foo = (struct foo_mesa_context *) ctx->DriverCtx;
  268.  
  269.    *width  = foo->Buffer->Width  = 12345;    /* XXX fix these */
  270.    *height = foo->Buffer->Height = 12345;
  271.  
  272. }
  273.  
  274.  
  275.  
  276. /**********************************************************************/
  277. /*****            Dummy functions                                 *****/
  278. /**********************************************************************/
  279.  
  280. static void WriteCIPixel( GLint x, GLint y, GLuint index )
  281. {
  282. }
  283.  
  284. static void WriteRGBAPixel( GLint x, GLint y, const GLubyte color[4] )
  285. {
  286. }
  287.  
  288. static void WriteRGBPixel( GLint x, GLint y, const GLubyte color[3] )
  289. {
  290. }
  291.  
  292. static GLuint ReadCIPixel( GLint x, GLint y )
  293. {
  294.    return 0;
  295. }
  296.  
  297. static void ReadRGBAPixel( GLint x, GLint y, GLubyte color[4] )
  298. {
  299. }
  300.  
  301. #define FLIP(y)  foo->Buffer->Height - (y) - 1;
  302.  
  303.  
  304. /**********************************************************************/
  305. /*****           Accelerated point, line, triangle rendering      *****/
  306. /**********************************************************************/
  307.  
  308.  
  309. /* There may several functions like this, for different screen modes, etc */
  310. static void fast_points_function( GLcontext *ctx, GLuint first, GLuint last )
  311. {
  312.    struct foo_mesa_context *foo = (struct foo_mesa_context *) ctx->DriverCtx;
  313.    struct vertex_buffer *VB = ctx->VB;
  314.    GLint i;
  315.  
  316.    /* Render a number of points by some hardware/OS accerated method */
  317.    if (VB->MonoColor) {
  318.       /* draw all points using the current color (set_color) */
  319.       for (i=first;i<=last;i++) {
  320.          if (VB->ClipMask[i]==0) {
  321.             /* compute window coordinate */
  322.             int x, y;
  323.             x =       (GLint) VB->Win[i][0];
  324.             y = FLIP( (GLint) VB->Win[i][1] );
  325.             WriteRGBAPixel(x, y, foo->CurrentColor);
  326.          }
  327.       }
  328.    }
  329.    else {
  330.       /* each point is a different color */
  331.       for (i=first;i<=last;i++) {
  332.          if (VB->ClipMask[i]==0) {
  333.             int x, y;
  334.             x =       (GLint) VB->Win[i][0];
  335.             y = FLIP( (GLint) VB->Win[i][1] );
  336.             WriteRGBAPixel(x, y, foo->CurrentColor);
  337.          }
  338.       }
  339.    }
  340. }
  341.  
  342.  
  343.  
  344.  
  345. /* There may several functions like this, for different screen modes, etc */
  346. static void fast_line_function( GLcontext *ctx, GLuint v0, GLuint v1, GLuint pv )
  347. {
  348.    /* Render a line by some hardware/OS accerated method */
  349.    struct foo_mesa_context *foo = (struct foo_mesa_context *) ctx->DriverCtx;
  350.    struct vertex_buffer *VB = ctx->VB;
  351.    int x0, y0, x1, y1;
  352.    GLubyte *pixel;
  353.  
  354.    if (VB->MonoColor) {
  355.       pixel = foo->CurrentColor;
  356.    }
  357.    else {
  358.       pixel = VB->Color[pv];
  359.    }
  360.  
  361.    x0 =       (int) VB->Win[v0][0];
  362.    y0 = FLIP( (int) VB->Win[v0][1] );
  363.    x1 =       (int) VB->Win[v1][0];
  364.    y1 = FLIP( (int) VB->Win[v1][1] );
  365.  
  366.    /* Draw line from (x0,y0) to (x1,y1) with current pixel color/index */
  367. }
  368.  
  369.  
  370.  
  371.  
  372. /* There may several functions like this, for different screen modes, etc */
  373. static void fast_triangle_function( GLcontext *ctx, GLuint v0,
  374.                                     GLuint v1, GLuint v2, GLuint pv )
  375. {
  376.    /* Render a triangle by some hardware/OS accerated method */
  377.    struct foo_mesa_context *foo = (struct foo_mesa_context *) ctx->DriverCtx;
  378.    struct vertex_buffer *VB = ctx->VB;
  379.    GLubyte *pixel;
  380.  
  381.    if (VB->MonoColor) {
  382.       pixel = foo->CurrentColor;
  383.    }
  384.    else {
  385.       pixel = VB->Color[pv];
  386.    }
  387.  
  388.    /* Draw triangle with current pixel color/index */
  389. }
  390.  
  391.  
  392.  
  393. /**********************************************************************/
  394. /*****            Write spans of pixels                           *****/
  395. /**********************************************************************/
  396.  
  397.  
  398. static void write_index8_span( const GLcontext *ctx,
  399.                                GLuint n, GLint x, GLint y,
  400.                                const GLubyte index[],
  401.                                const GLubyte mask[] )
  402. {
  403.    GLint i;
  404.    for (i=0;i<n;i++) {
  405.       if (mask[i]) {
  406.          WriteCIPixel(x+i, y, index[i]);
  407.       }
  408.    }
  409. }
  410.  
  411.  
  412. static void write_index32_span( const GLcontext *ctx,
  413.                                 GLuint n, GLint x, GLint y,
  414.                                 const GLuint index[],
  415.                                 const GLubyte mask[] )
  416. {
  417.    GLint i;
  418.    for (i=0;i<n;i++) {
  419.       if (mask[i]) {
  420.          WriteCIPixel(x+i, y, index[i]);
  421.       }
  422.    }
  423. }
  424.  
  425.  
  426.  
  427. static void write_mono_index_span( const GLcontext *ctx,
  428.                                    GLuint n, GLint x, GLint y,
  429.                                    const GLubyte mask[] )
  430. {
  431.    struct foo_mesa_context *foo = (struct foo_mesa_context *) ctx->DriverCtx;
  432.    GLuint i;
  433.    for (i=0;i<n;i++) {
  434.       if (mask[i]) {
  435.          WriteCIPixel(x+i, y, foo->CurrentIndex);
  436.       }
  437.    }
  438. }
  439.  
  440.  
  441.  
  442. static void write_rgba_span( const GLcontext *ctx, GLuint n, GLint x, GLint y,
  443.                              const GLubyte rgba[][4], const GLubyte mask[] )
  444. {
  445.    struct foo_mesa_context *foo = (struct foo_mesa_context *) ctx->DriverCtx;
  446.    GLuint i;
  447.    y = FLIP(y);
  448.    if (mask) {
  449.       /* draw some pixels */
  450.       for (i=0; i<n; i++) {
  451.          if (mask[i]) {
  452.             WriteRGBAPixel( x+i, y, foo->CurrentColor );
  453.          }
  454.       }
  455.    }
  456.    else {
  457.       /* draw all pixels */
  458.       for (i=0; i<n; i++) {
  459.          WriteRGBAPixel( x+i, y, foo->CurrentColor );
  460.       }
  461.    }
  462. }
  463.  
  464.  
  465. static void write_rgb_span( const GLcontext *ctx, GLuint n, GLint x, GLint y,
  466.                             const GLubyte rgb[][3], const GLubyte mask[] )
  467. {
  468.    struct foo_mesa_context *foo = (struct foo_mesa_context *) ctx->DriverCtx;
  469.    GLuint i;
  470.    y = FLIP(y);
  471.    if (mask) {
  472.       /* draw some pixels */
  473.       for (i=0; i<n; i++) {
  474.          if (mask[i]) {
  475.             WriteRGBPixel( x+i, y, rgb[i] );
  476.          }
  477.       }
  478.    }
  479.    else {
  480.       /* draw all pixels */
  481.       for (i=0; i<n; i++) {
  482.          WriteRGBPixel( x+i, y, rgb[i] );
  483.       }
  484.    }
  485. }
  486.  
  487.  
  488.  
  489. static void write_mono_rgba_span( const GLcontext *ctx,
  490.                                   GLuint n, GLint x, GLint y,
  491.                                   const GLubyte mask[])
  492. {
  493.    struct foo_mesa_context *foo = (struct foo_mesa_context *) ctx->DriverCtx;
  494.    GLint i;
  495.    y = FLIP(y);
  496.    for (i=0; i<n; i++) {
  497.       if (mask[i]) {
  498.          WriteRGBAPixel( x+i, y, foo->CurrentColor );
  499.       }
  500.    }
  501. }
  502.  
  503.  
  504.  
  505. /**********************************************************************/
  506. /*****                 Read spans of pixels                       *****/
  507. /**********************************************************************/
  508.  
  509.  
  510. static void read_index_span( const GLcontext *ctx,
  511.                              GLuint n, GLint x, GLint y, GLuint index[])
  512. {
  513.    GLint i;
  514.    for (i=0; i<n; i++) {
  515.       index[i] = ReadCIPixel( x+i, y );
  516.    }
  517. }
  518.  
  519.  
  520.  
  521. static void read_rgba_span( const GLcontext *ctx, GLuint n, GLint x, GLint y,
  522.                             GLubyte rgba[][4] )
  523. {
  524.    int i;
  525.    for (i=0; i<n; i++) {
  526.       ReadRGBAPixel( x+i, y, rgba[i] );
  527.    }
  528. }
  529.  
  530.  
  531.  
  532. /**********************************************************************/
  533. /*****              Write arrays of pixels                        *****/
  534. /**********************************************************************/
  535.  
  536.  
  537. static void write_index_pixels( const GLcontext *ctx,
  538.                                 GLuint n, const GLint x[], const GLint y[],
  539.                                 const GLuint index[], const GLubyte mask[] )
  540. {
  541.    GLint i;
  542.    for (i=0; i<n; i++) {
  543.       if (mask[i]) {
  544.          WriteCIPixel( x[i], y[i], index[i] );
  545.       }
  546.    }
  547. }
  548.  
  549.  
  550.  
  551. static void write_mono_index_pixels( const GLcontext *ctx,
  552.                                      GLuint n,
  553.                                      const GLint x[], const GLint y[],
  554.                                      const GLubyte mask[] )
  555. {
  556.    struct foo_mesa_context *foo = (struct foo_mesa_context *) ctx->DriverCtx;
  557.    GLint i;
  558.    for (i=0; i<n; i++) {
  559.       if (mask[i]) {
  560.          WriteCIPixel( x[i], y[i], foo->CurrentIndex );
  561.       }
  562.    }
  563. }
  564.  
  565.  
  566.  
  567. static void write_rgba_pixels( const GLcontext *ctx,
  568.                                GLuint n, const GLint x[], const GLint y[],
  569.                                const GLubyte rgba[][4], const GLubyte mask[] )
  570. {
  571.    GLint i;
  572.    for (i=0; i<n; i++) {
  573.       if (mask[i]) {
  574.          WriteRGBAPixel( x[i], y[i], rgba[i] );
  575.       }
  576.    }
  577. }
  578.  
  579.  
  580.  
  581. static void write_mono_rgba_pixels( const GLcontext *ctx,
  582.                                     GLuint n, const GLint x[], const GLint y[],
  583.                                     const GLubyte mask[] )
  584. {
  585.    struct foo_mesa_context *foo = (struct foo_mesa_context *) ctx->DriverCtx;
  586.    GLint i;
  587.    for (i=0; i<n; i++) {
  588.       if (mask[i]) {
  589.          WriteRGBAPixel( x[i], y[i], foo->CurrentColor );
  590.       }
  591.    }
  592. }
  593.  
  594.  
  595.  
  596.  
  597. /**********************************************************************/
  598. /*****                   Read arrays of pixels                    *****/
  599. /**********************************************************************/
  600.  
  601. /* Read an array of color index pixels. */
  602. static void read_index_pixels( const GLcontext *ctx,
  603.                                GLuint n, const GLint x[], const GLint y[],
  604.                                GLuint index[], const GLubyte mask[] )
  605. {
  606.    GLint i;
  607.    for (i=0; i<n; i++) {
  608.       if (mask[i]) {
  609.          index[i] = ReadCIPixel( x[i], y[i] );
  610.       }
  611.    }
  612. }
  613.  
  614.  
  615.  
  616. static void read_rgba_pixels( const GLcontext *ctx,
  617.                               GLuint n, const GLint x[], const GLint y[],
  618.                               GLubyte rgba[][4], const GLubyte mask[] )
  619. {
  620.    GLint i;
  621.    for (i=0; i<n; i++) {
  622.       if (mask[i]) {
  623.          ReadRGBAPixel( x[i], y[i], rgba[i] );
  624.       }
  625.    }
  626. }
  627.  
  628.  
  629.  
  630.  
  631. /**********************************************************************/
  632. /**********************************************************************/
  633.  
  634.  
  635. static void setup_DD_pointers( GLcontext *ctx )
  636. {
  637.    /* Initialize all the pointers in the DD struct.  Do this whenever */
  638.    /* a new context is made current or we change buffers via set_buffer! */
  639.  
  640.    ctx->Driver.UpdateState = setup_DD_pointers;
  641.  
  642.    ctx->Driver.ClearIndex = clear_index;
  643.    ctx->Driver.ClearColor = clear_color;
  644.    ctx->Driver.Clear = clear;
  645.  
  646.    ctx->Driver.Index = set_index;
  647.    ctx->Driver.Color = set_color;
  648.  
  649.    ctx->Driver.SetBuffer = set_buffer;
  650.    ctx->Driver.GetBufferSize = get_buffer_size;
  651.  
  652.    ctx->Driver.PointsFunc = fast_points_function;
  653.    ctx->Driver.LineFunc = fast_line_function;
  654.    ctx->Driver.TriangleFunc = fast_triangle_function;
  655.  
  656.    /* Pixel/span writing functions: */
  657.    ctx->Driver.WriteRGBASpan       = write_rgba_span;
  658.    ctx->Driver.WriteRGBSpan        = write_rgb_span;
  659.    ctx->Driver.WriteMonoRGBASpan   = write_mono_rgba_span;
  660.    ctx->Driver.WriteRGBAPixels     = write_rgba_pixels;
  661.    ctx->Driver.WriteMonoRGBAPixels = write_mono_rgba_pixels;
  662.  
  663.    ctx->Driver.WriteCI32Span       = write_index32_span;
  664.    ctx->Driver.WriteCI8Span        = write_index8_span;
  665.    ctx->Driver.WriteMonoCISpan     = write_mono_index_span;
  666.    ctx->Driver.WriteCI32Pixels     = write_index_pixels;
  667.    ctx->Driver.WriteMonoCIPixels   = write_mono_index_pixels;
  668.  
  669.    /* Pixel/span reading functions: */
  670.    ctx->Driver.ReadCI32Span        = read_index_span;
  671.    ctx->Driver.ReadRGBASpan        = read_rgba_span;
  672.    ctx->Driver.ReadCI32Pixels      = read_index_pixels;
  673.    ctx->Driver.ReadRGBAPixels      = read_rgba_pixels;
  674.  
  675.  
  676.    /*
  677.     * OPTIONAL FUNCTIONS:  these may be left uninitialized if the device
  678.     * driver can't/needn't implement them.
  679.     */
  680.    ctx->Driver.Finish = finish;
  681.    ctx->Driver.Flush = flush;
  682.    ctx->Driver.IndexMask = index_mask;
  683.    ctx->Driver.ColorMask = color_mask;
  684.    ctx->Driver.LogicOp = logicop;
  685.    ctx->Driver.Dither = dither;
  686. }
  687.  
  688.  
  689.  
  690. /**********************************************************************/
  691. /*****               FOO/Mesa Public API Functions                *****/
  692. /**********************************************************************/
  693.  
  694.  
  695.  
  696. /*
  697.  * The exact arguments to this function will depend on your window system
  698.  */
  699. FooMesaVisual FooMesaCreateVisual( GLboolean rgb_mode, GLboolean dbFlag,
  700.                                    GLint depthSize, GLint stencilSize,
  701.                                    GLint accumSize )
  702. {
  703.    FooMesaVisual v;
  704.    GLint redBits, greenBits, blueBits, alphaBits, indexBits;
  705.    GLboolean alphaFlag = GL_FALSE;
  706.  
  707.    v = (FooMesaVisual) calloc( 1, sizeof(struct foo_mesa_visual) );
  708.    if (!v) {
  709.       return NULL;
  710.    }
  711.  
  712.    if (rgb_mode) {
  713.       /* RGB(A) mode */
  714.       redBits = 8;         /* XXX 8 is just an example */
  715.       greenBits = 8;
  716.       blueBits = 8;
  717.       alphaBits = 8;
  718.       indexBits = 0;
  719.    }
  720.    else {
  721.       /* color index mode */
  722.       redBits = 0;
  723.       greenBits = 0;
  724.       blueBits = 0;
  725.       alphaBits = 0;
  726.       indexBits = 8;   /* XXX 8 is just an example */
  727.    }
  728.  
  729.    /* Create core visual */
  730.    v->gl_visual = gl_create_visual( rgb_mode, 
  731.                                     alphaFlag,
  732.                                     dbFlag,
  733.                                     GL_FALSE,  /* stereo */
  734.                                     depthSize,
  735.                                     stencilSize,
  736.                                     accumSize,
  737.                                     indexBits,
  738.                                     redBits, greenBits, blueBits, alphaBits );
  739.  
  740.    return v;
  741. }
  742.  
  743.  
  744.  
  745. void FooMesaDestroyVisual( FooMesaVisual v )
  746. {
  747.    gl_destroy_visual( v->gl_visual );
  748.    free( v );
  749. }
  750.  
  751.  
  752.  
  753.  
  754. FooMesaBuffer FooMesaCreateBuffer( FooMesaVisual visual,
  755.                                    void *your_window_id )
  756. {
  757.    FooMesaBuffer b;
  758.  
  759.    b = (FooMesaBuffer) calloc( 1, sizeof(struct foo_mesa_buffer) );
  760.    if (!b) {
  761.       return NULL;
  762.    }
  763.  
  764.    b->gl_buffer = gl_create_framebuffer( visual->gl_visual );
  765.    b->the_window = your_window_id;
  766.  
  767.    /* other stuff */
  768.  
  769.    return b;
  770. }
  771.  
  772.  
  773.  
  774. void FooMesaDestroyBuffer( FooMesaBuffer b )
  775. {
  776.    gl_destroy_framebuffer( b->gl_buffer );
  777.    free( b );
  778. }
  779.  
  780.  
  781.  
  782.  
  783. FooMesaContext FooMesaCreateContext( FooMesaVisual visual,
  784.                                      FooMesaContext share )
  785. {
  786.    FooMesaContext c;
  787.    GLboolean direct = GL_FALSE;
  788.  
  789.    c = (FooMesaContext) calloc( 1, sizeof(struct foo_mesa_context) );
  790.    if (!c) {
  791.       return NULL;
  792.    }
  793.  
  794.    c->gl_ctx = gl_create_context( visual->gl_visual,
  795.                                   share ? share->gl_ctx : NULL,
  796.                                   (void *) c, direct );
  797.  
  798.  
  799.    /* you probably have to do a bunch of other initializations here. */
  800.  
  801.    return c;
  802. }
  803.  
  804.  
  805.  
  806. void FooMesaDestroyContext( FooMesaContext c )
  807. {
  808.    gl_destroy_context( c->gl_ctx );
  809.    free( c );
  810. }
  811.  
  812.  
  813.  
  814. /*
  815.  * Make the specified context and buffer the current one.
  816.  */
  817. void FooMesaMakeCurrent( FooMesaContext c, FooMesaBuffer b )
  818. {
  819.    if (c && b) {
  820.       gl_make_current( c->gl_ctx, b->gl_buffer );
  821.       CurrentContext = c;
  822.       CurrentBuffer = b;
  823.       if (c->gl_ctx->Viewport.Width==0) {
  824.          /* initialize viewport to window size */
  825.          gl_Viewport( c->gl_ctx, 0, 0, c->Buffer->Width, c->Buffer->Height );
  826.       }
  827.    }
  828.    else {
  829.       /* Detach */
  830.       gl_make_current( NULL, NULL );
  831.       CurrentContext = 0;
  832.       CurrentBuffer = 0;
  833.    }
  834. }
  835.  
  836.  
  837.  
  838. void FooMesaSwapBuffers( FooMesaBuffer b )
  839. {
  840.    /* copy/swap back buffer to front if applicable */
  841. }
  842.  
  843.  
  844.  
  845. /* you may need to add other FOO/Mesa functions too... */
  846.  
  847.